package com.nostop.util;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nostop.exception.ParamException;
import org.apache.commons.collections4.MapUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.*;

public class BeanValidator {
    //定义全局的校验工厂
    private static ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

    //key为有问题的字段，value为出问题的原因
    //Class... group表示传入数组
     public static <T> Map<String,String> validate(T t,Class... group) {
         Validator validator = validatorFactory.getValidator();
         Set validateResult = validator.validate(t,group);
         if(validateResult.isEmpty()){
             return Collections.emptyMap();
         }else {
             LinkedHashMap errors = Maps.newLinkedHashMap();
             Iterator iterator = validateResult.iterator();
             while (iterator.hasNext()){
                 ConstraintViolation violation = (ConstraintViolation) iterator.next();
                 errors.put(violation.getPropertyPath().toString(), violation.getMessage());
             }
             return errors;
         }
     }

     public static Map<String,String> validateList(Collection<?> collection) {
         //Preconditions是java自带的校验类的工具,还有很多的其它的方法
         Preconditions.checkNotNull(collection);
         Iterator iterator = collection.iterator();
         Map errors;
         do {
             if(!iterator.hasNext()) {
                 return Collections.emptyMap();
             }
             Object object = iterator.next();
             //new Class[0]表示有零个元素的Class数组，即空数组，是为了符合的api的调用
             errors = validate(object,new Class[0]);
         }while (errors.isEmpty());
         return errors;
     }

     //用来包装上面的validate和validateList
    public static Map<String,String> validateObject(Object first,Object... objects) {
        if (objects != null && objects.length >0) {
            return validateList(Lists.asList(first,objects));
        }else {
            return validate(first,new Class[0]);
        }
    }


    public static void checkParam(Object param) throws ParamException {
         Map<String,String> map = BeanValidator.validateObject(param);
         if (MapUtils.isNotEmpty(map)) {
             throw new ParamException(map.toString());
         }
    }

}
